package com.moba.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.moba.bzuApiUtils.BzuApiUtil;
import com.moba.constants.Constant;
import com.moba.constants.ConstantKey;
import com.moba.response.ResponseBaseBean;
import io.swagger.annotations.ApiOperation;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.poi.ss.formula.functions.Rate;
import org.bitcoinj.core.ECKey;
import org.bitcoinj.core.NetworkParameters;
import org.bitcoinj.crypto.*;
import org.bitcoinj.params.MainNetParams;
import org.bitcoinj.wallet.DeterministicSeed;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.web3j.crypto.CipherException;
import org.web3j.crypto.ECKeyPair;
import org.web3j.crypto.Wallet;
import org.web3j.crypto.WalletFile;
import org.web3j.protocol.ObjectMapperFactory;
import org.web3j.utils.Numeric;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URLEncoder;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static com.alibaba.fastjson.JSON.parseObject;


public class WalletHelp {

    private static Logger logger = LoggerFactory.getLogger(WalletHelp.class);

    private static String  contractaddress = "0xf19d54ebd001d40642963882e583b75967b8c13c";//合约地址

    public static HDWalletModel createECR20Wallet(String password) {
        //TODO 密码长度这边校验一下  一般大于8就可以了
        //默认根地址
        String path="m/44'/60'/0'/0/0";
        String[] pathArray =path.split("/");
        long creationTimeSeconds = System.currentTimeMillis() / 1000;
        DeterministicSeed ds = new DeterministicSeed(new SecureRandom(), 128, "", creationTimeSeconds);
        //根私钥
        byte[] seedBytes = ds.getSeedBytes();
        //助记词
        List<String> mnemonic = ds.getMnemonicCode();
        try {
            //助记词种子
            byte[] mnemonicSeedBytes = MnemonicCode.INSTANCE.toEntropy(mnemonic);
            ECKeyPair mnemonicKeyPair = ECKeyPair.create(mnemonicSeedBytes);
            WalletFile walletFile = Wallet.createLight(password, mnemonicKeyPair);
            ObjectMapper objectMapper = ObjectMapperFactory.getObjectMapper();
            //存这个keystore 用完后删除
            String jsonStr = objectMapper.writeValueAsString(walletFile);
            //验证
            WalletFile checkWalletFile = objectMapper.readValue(jsonStr, WalletFile.class);
            ECKeyPair ecKeyPair = Wallet.decrypt(password, checkWalletFile);
            byte[] checkMnemonicSeedBytes = Numeric.hexStringToByteArray(ecKeyPair.getPrivateKey().toString(16));
            List<String> checkMnemonic = MnemonicCode.INSTANCE.toMnemonic(checkMnemonicSeedBytes);
        } catch (MnemonicException.MnemonicLengthException | MnemonicException.MnemonicWordException | MnemonicException.MnemonicChecksumException | CipherException | IOException e) {
            logger.error("账号生成异常！！！{}", e);
        }


        if (seedBytes == null) return null;
        DeterministicKey dkKey = HDKeyDerivation.createMasterPrivateKey(seedBytes);
        for (int i = 1; i < pathArray.length; i++) {
            ChildNumber childNumber;
            if (pathArray[i].endsWith("'")) {
                int number = Integer.parseInt(pathArray[i].substring(0,
                        pathArray[i].length() - 1));
                childNumber = new ChildNumber(number, true);
            } else {
                int number = Integer.parseInt(pathArray[i]);
                childNumber = new ChildNumber(number, false);
            }
            dkKey = HDKeyDerivation.deriveChildKey(dkKey, childNumber);
        }
        ECKeyPair keyPair = ECKeyPair.create(dkKey.getPrivKeyBytes());
        HDWalletModel hdWalletModel = null;
        try {
            WalletFile walletFile = Wallet.createLight(password, keyPair);
            ObjectMapper objectMapper = ObjectMapperFactory.getObjectMapper();
            hdWalletModel  = new HDWalletModel();
            hdWalletModel.setPassword(password);
            //keystore
            String jsonStr = objectMapper.writeValueAsString(walletFile);
            //私钥
            String privateKey=keyPair.getPrivateKey().toString(16);

            hdWalletModel.setPrivateKey(privateKey);
            //公钥
            String publicKey=keyPair.getPublicKey().toString(16);

            hdWalletModel.setPublicKey(publicKey);
            //根地址
            String rpath = dkKey.getPathAsString();
            //地址
            String address="0x" + walletFile.getAddress();

            hdWalletModel.setAddress(address);

        } catch (CipherException | JsonProcessingException e) {
            logger.error("账号生成异常！！！{}", e);
        }
        return hdWalletModel;
    }

    public  static void main(String []args){

        System.out.println(getExchangeRate("GHMI"));
        //  String contractaddress = "0xf19d54ebd001d40642963882e583b75967b8c13c";
        //   String  address = "0x350d5474b57cf45fa3ad9d39faf782e1ad77b57b";

        //  System.out.println(getERC20Balance(address));
//         String  address  =  "1PW4uCbmSkPX2qXPsicY38fF38ghUvx71z";

        // String  address  =  "1Lj3qvarMoeuE33pVbSCjxUnxzKrq5stBB";

//         String  usdtBalance = getUSDTBalance(address);
//         System.out.println(usdtBalance);

        // String  result =   getUSDT2NUCRate();

        // System.out.println(result);

        //createECR20Wallet("123456");

        // System.out.println(getHasPay("18689675657","513186"));

        //  System.out.println("::::"+ new Date().getTime());

    }


    public static String getERC20Balance(String address){
        //创建客户端
        CloseableHttpClient httpClient = HttpClients.createDefault();
        //拼接uri
        String uri = "https://api.etherscan.io/api?module=account&action=tokenbalance&contractaddress=%s&address=%s&tag=latest";
        //格式化
        String format = String.format(uri, contractaddress,address);
        //创建请求
        HttpGet httpGet = new HttpGet(format);
        try {
            //调用接口，返回结果
            CloseableHttpResponse response = httpClient.execute(httpGet);
            if (response!=null){
                HttpEntity entity = response.getEntity();
                String result = EntityUtils.toString(entity,"UTF-8");
                String nuc  = parseObject(result).get("result").toString();
                BigInteger  userBalance = new BigInteger(nuc).divide(new BigInteger("10").pow(18));
                return userBalance.toString();
            }else{
                return "nuc  response  null";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "explore  nuc response has  Exception";
    }


    public static HDWalletModel  createUSDTWallet(String password){

        HDWalletModel  hdWalletModel  = new HDWalletModel();

        NetworkParameters params =  MainNetParams.get();
        ECKey key = new ECKey();
        hdWalletModel.setPassword(password);
        hdWalletModel.setAddress(key.toAddress(params).toString());

        //hdWalletModel.setPrivateKey(key.getPrivateKeyAsHex());
        hdWalletModel.setPrivateKey(key.getPrivateKeyAsWiF(params));

        hdWalletModel.setPublicKey( key.getPublicKeyAsHex());


        logger.warn("私钥 => {}", key.getPrivateKeyAsHex());
        logger.warn("公钥 => {}", key.getPublicKeyAsHex());
        logger.warn("地址 => {}", key.toAddress(params));

        System.out.println(key.toAddress(params).toString());

        return hdWalletModel;

    }

    public static String getUSDTBalance(String address) {

        String result = null;


        //拼接uri
        String url = "https://api.omniexplorer.info/v1/address/addr/";
        HttpPost httpPost = new HttpPost(url);
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("addr", address));
        // 创建form表单对象
        UrlEncodedFormEntity formEntity = null;
        CloseableHttpClient httpClient = null ;
        try {
            formEntity = new UrlEncodedFormEntity(params, "utf-8");
            formEntity.setContentType("application/x-www-form-urlencoded");
            // 把表单对象设置到httpPost中
            httpPost.setEntity(formEntity);
            // 使用HttpClient发起请求，返回response
            httpClient = HttpClients.createDefault();
            CloseableHttpResponse response = httpClient.execute(httpPost);

            if (response != null) {
                HttpEntity entity = response.getEntity();
                result = EntityUtils.toString(entity, "UTF-8");
                JSONArray arr =  JSONArray.parseArray(parseObject(result).get("balance").toString());
                System.out.println(arr.toString());
                JSONObject usdt = (JSONObject)arr.stream().filter(o-> JSONArray.parseObject(o.toString()).get("symbol").equals("SP31")).findFirst().get();

                System.out.println(usdt.toString());
                BigInteger  userBalance = new BigInteger(usdt.get("value").toString()).divide(new BigInteger("10").pow(8));
                result = userBalance.toString();
            } else {
                result ="0";
            }

        } catch (Exception e) {
            e.printStackTrace();
            result ="0";
        }

        return result;

    }


    public static String   getUSDT2NUCRate(){
        String  result = null;
        String command = "python3 /Users/vincent/Desktop/abc/nuc2usdt.py";
        //String command =  "python  C://Users//Administrator//Desktop//box//nuc2usdt.py";

        try {
            Process process = Runtime.getRuntime().exec(command);
            //process.waitFor();
            InputStreamReader ir = new InputStreamReader(process.getInputStream());
            LineNumberReader input = new LineNumberReader(ir);
            result = input.readLine();
            input.close();
            ir.close();
            //process.waitFor();
        } catch (IOException e) {
            logger.error("调用python脚本并读取结果时出错：" + e.getMessage());
        }
        return result;


    }



    /**
     * 汇率折算
     *
     * @param shortName 币种简写 比如：CNY
     * @return Map key为币种 value为所查法币对应的值
     */

    public static BigDecimal getExchangeRate(String shortName) {

        String method = "/coin/exchange";
        String param = "shortName=" + shortName + "&accessKey=" + URLEncoder.encode(ConstantKey.ACCESS_KEY);
        String returnJson = BzuApiUtil.sendGet(method, param);
        Map<String, Object> maps = JSON.parseObject(returnJson, Map.class);
        Map<String, Object> dataList = (Map) maps.get("data");
        BigDecimal ghmi_rate =new BigDecimal(0);
        try {
            ghmi_rate =new BigDecimal(dataList.get("GHMI").toString());

        }catch (Exception e){
            logger.error("调用获取汇率时出错：" + e.getMessage());
        }

        return  ghmi_rate;
    }


}


